<?php

namespace App\Repositories;

use Exception;
use App\Models\Image;
use Illuminate\Support\Str;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;
use App\Exceptions\GeneralException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;

/**
 * 图片处理逻辑
 *
 * Date: 29/04/2018
 * @author George
 * @package App\Repositories
 */
class ImageRepository
{
	/**
	 * 创建图片资源
	 *
	 * Date: 29/04/2018
	 * @author George
	 * @param array $images
	 * @param int $user_id
	 * @param int $company_id
	 * @param int $project_id
	 * @param Model $imagetable
	 * @return \Illuminate\Support\Collection
	 * @throws GeneralException|Exception
	 */
	public function store(array $images, int $user_id, int $company_id, int $project_id, Model $imagetable)
	{
		$result = collect([]);
		// 获取模型的关联类型
		$category = Str::snake(class_basename($imagetable));
		// 生成存储前缀
		$prefix = "public/{$category}";

		try {
			// 开启事务
			DB::beginTransaction();
			foreach ($images as $image) {
				/**
				 * @var UploadedFile $image
				 */
				$path = $image->store($prefix);
				$instance = Image::create([
					'path' => Storage::url($path),
					'company_id' => $company_id,
					'project_id' => $project_id,
					'user_id' => $user_id,
					'imagetable_id' => $imagetable->getKey(),
					'imagetable_type' => $category,
				]);
				$result->push($instance);
			}
			// 提交事务
			DB::commit();
			return $result;
		} catch (Exception $exception) {
			// 回滚事务
			DB::rollBack();
			// 删除文件
			$result->map(function ($image) {
				Storage::disk('public')->delete(str_after($image->path, '/storage/'));
			});
			throw new GeneralException('上传图片信息失败');
		}
	}

	/**
	 * 删除文件资源
	 *
	 * Date: 29/04/2018
	 * @author George
	 * @param Image $image
	 * @return bool|null
	 * @throws Exception
	 */
	public function destroy(Image $image)
	{
		$result = Storage::disk('public')->delete(str_after($image->path, '/storage/'));

		if ($result) {
			return $image->delete();
		}

		throw new GeneralException('删除文件失败');
	}

	/**
	 * 压缩原始图片生成缩略图
	 * 同时更新图片数据资源的压缩图片路径
	 *
	 * Date: 29/04/2018
	 * @author George
	 * @param Image $image
	 */
	protected function compress(Image $image)
	{
		// TODO 功能待定
	}
}
